package display3d.away3d
{
	import away3d.containers.ObjectContainer3D;
	import away3d.core.base.Object3D;
	import away3d.materials.ShadingColorMaterial;
	import away3d.primitives.Cone;
	import flash.geom.Vector3D;
	import jazztures.geom.Point3D;
	import jazztures.plugins.away3d.Skeleton3D;
	import jazztures.utils.GeometryUtils;
	
	
	
	public class Doll3D extends Skeleton3D
	{
		protected var upperStomach3D:Object3D;
		protected var lowerStomach3D:Object3D;
		
		protected var waist3D:Object3D;
		
		protected var leftArm3D:Object3D;
		protected var leftForeArm3D:Object3D;
		
		protected var leftThigh3D:Object3D;
		protected var leftCalf3D:Object3D;
		
		protected var rightArm3D:Object3D;
		protected var rightForeArm3D:Object3D;
		
		protected var rightThigh3D:Object3D;
		protected var rightCalf3D:Object3D;
		
		protected var upperStomach:Point3D;
		protected var lowerStomach:Point3D;
		
		protected var waist:Point3D;
		
		protected var leftArm:Point3D;
		protected var leftForeArm:Point3D;
		
		protected var leftThigh:Point3D;
		protected var leftCalf:Point3D;
		
		protected var rightArm:Point3D;
		protected var rightForeArm:Point3D;
		
		protected var rightThigh:Point3D;
		protected var rightCalf:Point3D;
		
		public function Doll3D()
		{
			super();
		}
		
		override protected function build():void{
			material = new ShadingColorMaterial(Math.random()*0xFFFFFF);
			
			head3D = getDefaultJoint();
			addChild(head3D);
			
			neck3D = getDefaultJoint();
			addChild(neck3D);
			
			upperStomach3D = getCone();
			addChild(upperStomach3D);
			
			torso3D = getDefaultJoint();
			addChild(torso3D);
			
			lowerStomach3D = getCone();
			addChild(lowerStomach3D);
			
			waist3D = getDefaultJoint();
			addChild(waist3D);
			
			leftShoulder3D = getDefaultJoint();
			addChild(leftShoulder3D);
			
			leftArm3D = getDefaultJoint();
			addChild(leftArm3D);
			
			leftElbow3D = getDefaultJoint();
			addChild(leftElbow3D);
			
			leftForeArm3D = getDefaultJoint();
			addChild(leftForeArm3D);
			
			leftHand3D = getDefaultJoint();
			addChild(leftHand3D);
			
			rightShoulder3D = getDefaultJoint();
			addChild(rightShoulder3D);
			
			rightArm3D = getDefaultJoint();
			addChild(rightArm3D);
			
			rightElbow3D = getDefaultJoint();
			addChild(rightElbow3D);
			
			rightForeArm3D = getDefaultJoint();
			addChild(rightForeArm3D);
			
			rightHand3D = getDefaultJoint();
			addChild(rightHand3D);
			
			leftHip3D = getDefaultJoint();
			addChild(leftHip3D);
			
			leftThigh3D = getDefaultJoint();
			addChild(leftThigh3D);
			
			leftKnee3D = getDefaultJoint();
			addChild(leftKnee3D);
			
			leftCalf3D = getDefaultJoint();
			addChild(leftCalf3D);
			
			leftFoot3D = getDefaultJoint();
			addChild(leftFoot3D);
			
			rightHip3D = getDefaultJoint();
			addChild(rightHip3D);
			
			rightThigh3D = getDefaultJoint();
			addChild(rightThigh3D);
			
			rightKnee3D = getDefaultJoint();
			addChild(rightKnee3D);
			
			rightCalf3D = getDefaultJoint();
			addChild(rightCalf3D);
			
			rightFoot3D = getDefaultJoint();
			addChild(rightFoot3D);
		}
		
		protected function getCone():Object3D{
			var cone:Cone = new Cone({material:material});
			var container:ObjectContainer3D = new ObjectContainer3D();
			cone.radius = 20;
			cone.height = 80;
			cone.rotationX = 90;
			container.addChild(cone);
			return container;
		}
		
		protected function calculateAditionalPoints():void{
			
			var upperStomachPos:Vector3D = GeometryUtils.getMiddlePoint(neck.vector3D, torso.vector3D);
			upperStomach = new Point3D(upperStomachPos.x, upperStomachPos.y, upperStomachPos.z);
			
			var waistPos:Vector3D = GeometryUtils.getMiddlePoint(leftHip.vector3D, rightHip.vector3D);
			waist = new Point3D(waistPos.x, waistPos.y, waistPos.z);
			
			var lowerStomachPos:Vector3D = GeometryUtils.getMiddlePoint(torso.vector3D, waist.vector3D);
			lowerStomach = new Point3D(lowerStomachPos.x, lowerStomachPos.y, lowerStomachPos.z);
			
			var leftArmPos:Vector3D = GeometryUtils.getMiddlePoint(leftShoulder.vector3D, leftElbow.vector3D);
			leftArm = new Point3D(leftArmPos.x, leftArmPos.y, leftArmPos.z);
			
			var leftForeArmPos:Vector3D = GeometryUtils.getMiddlePoint(leftElbow.vector3D, leftHand.vector3D);
			leftForeArm = new Point3D(leftForeArmPos.x, leftForeArmPos.y, leftForeArmPos.z);
			
			var leftThighPos:Vector3D = GeometryUtils.getMiddlePoint(leftHip.vector3D, leftKnee.vector3D);
			leftThigh = new Point3D(leftThighPos.x, leftThighPos.y, leftThighPos.z);
			
			var leftCalfPos:Vector3D = GeometryUtils.getMiddlePoint(leftKnee.vector3D, leftFoot.vector3D);
			leftCalf = new Point3D(leftCalfPos.x, leftCalfPos.y, leftCalfPos.z);
			
			var rightArmPos:Vector3D = GeometryUtils.getMiddlePoint(rightShoulder.vector3D, rightElbow.vector3D);
			rightArm = new Point3D(rightArmPos.x, rightArmPos.y, rightArmPos.z);
			
			var rightForeArmPos:Vector3D = GeometryUtils.getMiddlePoint(rightElbow.vector3D, rightHand.vector3D);
			rightForeArm = new Point3D(rightForeArmPos.x, rightForeArmPos.y, rightForeArmPos.z);
			
			var rightThighPos:Vector3D = GeometryUtils.getMiddlePoint(rightHip.vector3D, rightKnee.vector3D);
			rightThigh = new Point3D(rightThighPos.x, rightThighPos.y, rightThighPos.z);
			
			var rightCalfPos:Vector3D = GeometryUtils.getMiddlePoint(rightKnee.vector3D, rightFoot.vector3D);
			rightCalf = new Point3D(rightCalfPos.x, rightCalfPos.y, rightCalfPos.z);
		}
		
		protected function calculateRotations():void{
			head.rotationY = GeometryUtils.getYaw(neck.vector3D, head.vector3D, true);
			head.rotationX = GeometryUtils.getPitch(neck.vector3D, head.vector3D, true);
			
			neck.rotationY = GeometryUtils.getYaw(leftShoulder.vector3D, rightShoulder.vector3D, true);
			neck.rotationX = GeometryUtils.getPitch(leftShoulder.vector3D, rightShoulder.vector3D, true);
			
			upperStomach.rotationY = GeometryUtils.getYaw(neck.vector3D, torso.vector3D, true);
			upperStomach.rotationX = GeometryUtils.getPitch(neck.vector3D, torso.vector3D, true);
			
			waist.rotationY = GeometryUtils.getYaw(leftHip.vector3D, rightHip.vector3D, true);
			waist.rotationX = GeometryUtils.getPitch(leftHip.vector3D, rightHip.vector3D, true);
			
			lowerStomach.rotationY = GeometryUtils.getYaw(waist.vector3D, torso.vector3D, true);
			lowerStomach.rotationX = GeometryUtils.getPitch(waist.vector3D, torso.vector3D, true);
			
			leftArm.rotationY = GeometryUtils.getYaw(leftShoulder.vector3D, leftElbow.vector3D, true);
			leftArm.rotationX = GeometryUtils.getPitch(leftShoulder.vector3D, leftElbow.vector3D, true);
			
			leftForeArm.rotationY = GeometryUtils.getYaw(leftElbow.vector3D, leftHand.vector3D, true);
			leftForeArm.rotationX = GeometryUtils.getPitch(leftElbow.vector3D, leftHand.vector3D, true);
			
			leftThigh.rotationY = GeometryUtils.getYaw(leftHip.vector3D, leftKnee.vector3D, true);
			leftThigh.rotationX = GeometryUtils.getPitch(leftHip.vector3D, leftKnee.vector3D, true);
			
			leftCalf.rotationY = GeometryUtils.getYaw(leftKnee.vector3D, leftFoot.vector3D, true);
			leftCalf.rotationX = GeometryUtils.getPitch(leftKnee.vector3D, leftFoot.vector3D, true);
			
			rightArm.rotationY = GeometryUtils.getYaw(rightShoulder.vector3D, rightElbow.vector3D, true);
			rightArm.rotationX = GeometryUtils.getPitch(rightShoulder.vector3D, rightElbow.vector3D, true);
			
			rightForeArm.rotationY = GeometryUtils.getYaw(rightElbow.vector3D, rightHand.vector3D, true);
			rightForeArm.rotationX = GeometryUtils.getPitch(rightElbow.vector3D, rightHand.vector3D, true);
			
			rightThigh.rotationY = GeometryUtils.getYaw(rightHip.vector3D, rightKnee.vector3D, true);
			rightThigh.rotationX = GeometryUtils.getPitch(rightHip.vector3D, rightKnee.vector3D, true);
			
			rightCalf.rotationY = GeometryUtils.getYaw(rightKnee.vector3D, rightFoot.vector3D, true);
			rightCalf.rotationX = GeometryUtils.getPitch(rightKnee.vector3D, rightFoot.vector3D, true);
		}
		
		protected function setSizes():void{
			setDepth(head3D, GeometryUtils.getDistance(head.vector3D, neck.vector3D));
			
			setDepth(neck3D, GeometryUtils.getDistance(leftShoulder.vector3D, rightShoulder.vector3D));
			
			setDepth(upperStomach3D, GeometryUtils.getDistance(neck.vector3D, torso.vector3D));
			setDepth(lowerStomach3D, GeometryUtils.getDistance(torso.vector3D, waist.vector3D));
			
			setDepth(waist3D, GeometryUtils.getDistance(leftHip.vector3D, rightHip.vector3D));
			
			setDepth(leftArm3D, GeometryUtils.getDistance(leftShoulder.vector3D, leftElbow.vector3D));
			setDepth(leftForeArm3D, GeometryUtils.getDistance(leftElbow.vector3D, leftHand.vector3D));
			
			setDepth(leftThigh3D, GeometryUtils.getDistance(leftHip.vector3D, leftKnee.vector3D));
			setDepth(leftCalf3D, GeometryUtils.getDistance(leftKnee.vector3D, leftFoot.vector3D));
			
			setDepth(rightArm3D, GeometryUtils.getDistance(rightShoulder.vector3D, rightElbow.vector3D));
			setDepth(rightForeArm3D, GeometryUtils.getDistance(rightElbow.vector3D, rightHand.vector3D));
			
			setDepth(rightThigh3D, GeometryUtils.getDistance(rightHip.vector3D, rightKnee.vector3D));
			setDepth(rightCalf3D, GeometryUtils.getDistance(rightKnee.vector3D, rightFoot.vector3D));
		}
		
		private function setDepth(object:Object3D, depth:Number):void{
			object.scaleZ = depth/(object.maxZ*2);
		}
		
		override public function update():void{
			calculateAditionalPoints();
			setSizes();
			calculateRotations();
			
			setPositionAndRotation(head3D , head);
			setPositionAndRotation(neck3D, neck);
			setPositionAndRotation(upperStomach3D, upperStomach);
			setPositionAndRotation(torso3D, torso);
			setPositionAndRotation(lowerStomach3D, lowerStomach);
			setPositionAndRotation(waist3D, waist);
			
			setPositionAndRotation(leftShoulder3D,  leftShoulder);
			setPositionAndRotation(leftArm3D, leftArm);
			setPositionAndRotation(leftElbow3D,  leftElbow);
			setPositionAndRotation(leftForeArm3D, leftForeArm);
			setPositionAndRotation(leftHand3D,  leftHand);
			
			setPositionAndRotation(rightShoulder3D,  rightShoulder);
			setPositionAndRotation(rightArm3D, rightArm);
			setPositionAndRotation(rightElbow3D,  rightElbow);
			setPositionAndRotation(rightForeArm3D, rightForeArm);
			setPositionAndRotation(rightHand3D,  rightHand);
			
			setPositionAndRotation(leftHip3D,  leftHip);
			setPositionAndRotation(leftThigh3D,  leftThigh);
			setPositionAndRotation(leftKnee3D,  leftKnee);
			setPositionAndRotation(leftCalf3D,  leftCalf);
			setPositionAndRotation(leftFoot3D,  leftFoot);
			
			setPositionAndRotation(rightHip3D,  rightHip);
			setPositionAndRotation(rightThigh3D,  rightThigh);
			setPositionAndRotation(rightKnee3D,  rightKnee);
			setPositionAndRotation(rightCalf3D,  rightCalf);
			setPositionAndRotation(rightFoot3D,  rightFoot);
		}
	}
}